home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume15 / dmake-3.6 / part21 < prev    next >
Encoding:
Text File  |  1990-10-14  |  39.4 KB  |  1,319 lines

  1. Newsgroups: comp.sources.misc
  2. X-UNIX-From: dvadura@watdragon.waterloo.edu
  3. subject: v15i073: dmake version 3.6 (part 21/25)
  4. from: Dennis Vadura <dvadura@watdragon.waterloo.edu>
  5. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  6.  
  7. Posting-number: Volume 15, Issue 73
  8. Submitted-by: Dennis Vadura <dvadura@watdragon.waterloo.edu>
  9. Archive-name: dmake-3.6/part21
  10.  
  11. #!/bin/sh
  12. # this is part 21 of a multipart archive
  13. # do not concatenate these parts, unpack them in order with /bin/sh
  14. # file expand.c continued
  15. #
  16. CurArch=21
  17. if test ! -r s2_seq_.tmp
  18. then echo "Please unpack part 1 first!"
  19.      exit 1; fi
  20. ( read Scheck
  21.   if test "$Scheck" != $CurArch
  22.   then echo "Please unpack part $Scheck next!"
  23.        exit 1;
  24.   else exit 0; fi
  25. ) < s2_seq_.tmp || exit 1
  26. echo "x - Continuing file expand.c"
  27. sed 's/^X//' << 'SHAR_EOF' >> expand.c
  28. X--        $($(A)) - represents macro indirection
  29. X--        <+...+> - get mapped to $(mktmp ...)
  30. X--    
  31. X--        following macro is recognized
  32. X--        
  33. X--                string1{ token_list }string2
  34. X--                
  35. X--        and expands to string1 prepended to each element of token_list and
  36. X--        string2 appended to each of the resulting tokens from the first
  37. X--        operation.  If string2 is of the form above then the result is
  38. X--        the cross product of the specified (possibly modified) token_lists.
  39. X--        
  40. X--        The folowing macro modifiers are defined and expanded:
  41. X--        
  42. X--               $(macro:modifier_list:modifier_list:...)
  43. X--               
  44. X--        where modifier_list a combination of:
  45. X--        
  46. X--               D or d      - Directory portion of token including separator
  47. X--               F or f      - File portion of token including suffix
  48. X--               B or b      - basename portion of token not including suffix
  49. X--         T or t      - for tokenization
  50. X--
  51. X--      or a single
  52. X--               S or s      - pattern substitution (simple)
  53. X--               
  54. X--        NOTE:  Modifiers are applied once the macro value has been found.
  55. X--               Thus the construct $($(test):s/joe/mary/) is defined and
  56. X--               modifies the value of $($(test))
  57. X--
  58. X--           Also the construct $(m:d:f) is not the same as $(m:df)
  59. X--           the first applies d to the value of $(m) and then
  60. X--           applies f to the value of that whereas the second form
  61. X--           applies df to the value of $(m).
  62. X--
  63. X-- AUTHOR
  64. X--      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  65. X--      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  66. X--
  67. X-- COPYRIGHT
  68. X--      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  69. X-- 
  70. X--      This program is free software; you can redistribute it and/or
  71. X--      modify it under the terms of the GNU General Public License
  72. X--      (version 1), as published by the Free Software Foundation, and
  73. X--      found in the file 'LICENSE' included with this distribution.
  74. X-- 
  75. X--      This program is distributed in the hope that it will be useful,
  76. X--      but WITHOUT ANY WARRANTY; without even the implied warrant of
  77. X--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  78. X--      GNU General Public License for more details.
  79. X-- 
  80. X--      You should have received a copy of the GNU General Public License
  81. X--      along with this program;  if not, write to the Free Software
  82. X--      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  83. X--
  84. X-- LOG
  85. X--     $Log:    expand.c,v $
  86. X * Revision 1.1  90/10/06  12:03:40  dvadura
  87. X * dmake Release, Version 3.6
  88. X * 
  89. X*/
  90. X
  91. X#include <ctype.h>
  92. X#include "extern.h"
  93. X#include "alloc.h"
  94. X#include "db.h"
  95. X
  96. Xstatic    char*    _scan_token ANSI((char*, char**));
  97. Xstatic    char*    _scan_macro ANSI((char*, char**));
  98. Xstatic    char*    _scan_brace ANSI((char*, char**, int*));
  99. Xstatic    char*    _cross_prod ANSI((char*, char*));
  100. Xstatic    char*    _apply_modifiers ANSI((int, char*));
  101. Xstatic    char*    _tokenize ANSI((char*, char*));
  102. X
  103. X#define SUFFIX_FLAG    1        /* defines for macro modifier code */
  104. X#define DIRECTORY_FLAG    2
  105. X#define FILE_FLAG    4
  106. X
  107. X
  108. Xchar *
  109. XExpand( src )/*
  110. X===============
  111. X      This is the driver routine for the expansion, it identifies non-white
  112. X      space tokens and gets the _scan_token routine to figure out if they should
  113. X      be treated in a special way. */
  114. X
  115. Xchar *src;                    /* pointer to source string  */
  116. X{
  117. X   char  *tmp;              /* pointer to temporary str  */
  118. X   char  *res;                /* pointer to result string  */
  119. X   char  *start;              /* pointer to start of token */
  120. X   
  121. X   DB_ENTER( "Expand" );
  122. X   DB_PRINT( "exp", ("Expanding [%s]", src) );
  123. X
  124. X   res = _strdup( "" );
  125. X   if( src == NIL(char) ) DB_RETURN( res );
  126. X
  127. X   while( *src ) {
  128. X      char *ks, *ke;
  129. X
  130. X      /* Here we find the next non white space token in the string
  131. X       * and find it's end, with respect to non-significant white space. */
  132. X      
  133. X      start = _strspn( src, " \t\n" );
  134. X      res   = _strjoin( res, src, start-src, TRUE );
  135. X      if( !(*start) ) break;
  136. X
  137. X      /* START <+...+> KLUDGE */
  138. X      if( (ks=_strstr(start,"<+")) && (ke=_strstr(ks,"+>")) ){
  139. X     char *t1, *t2;
  140. X
  141. X     res = _strjoin( res, t2=Expand(t1=_substr(start,ks)), -1, TRUE);
  142. X     FREE(t1); FREE(t2);
  143. X
  144. X     t1 = _substr(ks+2, ke+1); t1[ke-ks-2] = ')';
  145. X     t2 = _strjoin( "$(mktmp ", t1, -1,FALSE);
  146. X     FREE(t1);
  147. X     res = _strjoin( res, t2=Expand(t2), -1, TRUE);
  148. X     FREE(t2);
  149. X     src = ke+2;
  150. X      }
  151. X      /* END <+...+> KLUDGE */
  152. X      else {
  153. X     res   = _strjoin( res, tmp = _scan_token( start, &src ), -1, TRUE );
  154. X     FREE( tmp );
  155. X      }
  156. X   }
  157. X   
  158. X   DB_PRINT( "exp", ("Returning [%s]", res) );
  159. X   DB_RETURN( res );
  160. X}
  161. X
  162. X
  163. X
  164. Xchar *
  165. XApply_edit( src, pat, subst, fr, anchor )/*
  166. X===========================================
  167. X   Take the src string and apply the pattern substitution.  ie. look for
  168. X   occurrences of pat in src and replace each occurrence with subst.  This is
  169. X   NOT a regular expressions pattern substitution, it's just not worth it.
  170. X   
  171. X   if anchor == TRUE then the src pattern match must be at the end of a token.
  172. X   ie. this is for SYSV compatibility and is only used for substitutions of
  173. X   the caused by $(macro:pat=sub).  So if src = "fre.o.k june.o" then
  174. X   $(src:.o=.a) results in "fre.o.k june.a", and $(src:s/.o/.a) results in
  175. X   "fre.a.k june.a" */
  176. X
  177. Xchar *src;            /* the source string */
  178. Xchar *pat;            /* pattern to find   */
  179. Xchar *subst;            /* substitute string */
  180. Xint   fr;            /* if TRUE free src  */
  181. Xint   anchor;            /* if TRUE anchor    */
  182. X{
  183. X   char *res;
  184. X   char *p;
  185. X   char *s;
  186. X   int   l;
  187. X
  188. X   DB_ENTER( "Apply_edit" );
  189. X   
  190. X   if( !*pat ) DB_RETURN( src );        /* do nothing if pat is NULL */
  191. X
  192. X   DB_PRINT( "mod", ("Source str:  [%s]", src) );
  193. X   DB_PRINT( "mod", ("Replacing [%s], with [%s]", pat, subst) );
  194. X
  195. X   s   = src;
  196. X   l   = strlen( pat );
  197. X   if( (p = _strstr( s, pat )) != NIL(char) ) {
  198. X      res = _strdup( "" );
  199. X      do {
  200. X     if( anchor )
  201. X        if( !*(p+l) || (strchr(" \t", *(p+l)) != NIL(char)) )
  202. X           res = _strjoin( _strjoin( res, s, p-s, TRUE ), subst, -1, TRUE );
  203. X        else
  204. X           res = _strjoin( res, s, p+l-s, TRUE );
  205. X     else
  206. X        res = _strjoin( _strjoin( res, s, p-s, TRUE ), subst, -1, TRUE );
  207. X
  208. X     s   = p + l;
  209. X      }
  210. X      while( (p = _strstr( s, pat )) != NIL(char) );
  211. X
  212. X      res = _strjoin( res, s, -1, TRUE );
  213. X      if( fr ) FREE( src );
  214. X   }
  215. X   else
  216. X      res = src;
  217. X
  218. X
  219. X   DB_PRINT( "mod", ("Result [%s]", res) );
  220. X   DB_RETURN( res );
  221. X}
  222. X
  223. X
  224. X
  225. Xvoid
  226. XMap_esc( tok )/*
  227. X================
  228. X   Map an escape sequence and replace it by it's corresponding character
  229. X   value.  It is assumed that tok points at the initial \, the esc
  230. X   sequence in the original string is replaced and the value of tok
  231. X   is not modified. */
  232. Xchar *tok;
  233. X{
  234. X   if( strchr( "\"\\vantbrf01234567", tok[1] ) ) {
  235. X      switch( tok[1] ) {
  236. X     case 'a' : *tok = 0x07; break;
  237. X     case 'b' : *tok = '\b'; break;
  238. X     case 'f' : *tok = '\f'; break;
  239. X     case 'n' : *tok = '\n'; break;
  240. X     case 'r' : *tok = '\r'; break;
  241. X     case 't' : *tok = '\t'; break;
  242. X     case 'v' : *tok = 0x0b; break;
  243. X     case '\\': *tok = '\\'; break;
  244. X     case '\"': *tok = '\"'; break;
  245. X
  246. X     default: {
  247. X        register int i = 0;
  248. X        register int j = 0;
  249. X        for( ; i<2 && isdigit(tok[2]); i++ ) {
  250. X           j = (j << 3) + (tok[1] - '0');
  251. X           strcpy( tok+1, tok+2 );
  252. X        }
  253. X        j = (j << 3) + (tok[1] - '0');
  254. X        *tok = j;
  255. X     }
  256. X      }
  257. X      strcpy( tok+1, tok+2 );
  258. X   }
  259. X}
  260. X
  261. X
  262. X
  263. Xstatic char*
  264. X_scan_token( s, ps )/*
  265. X======================
  266. X      This routine scans the token characters one at a time and identifies
  267. X      macros starting with $( and ${ and calls _scan_macro to expand their
  268. X      value.   the string1{ token_list }string2 expansion is also handled.
  269. X      In this case a temporary result is maintained so that we can take it's
  270. X      cross product with any other token_lists that may possibly appear. */
  271. X      
  272. Xchar *s;        /* pointer to start of src string */
  273. Xchar **ps;        /* pointer to start pointer      */
  274. X{
  275. X   char *res;                 /* pointer to result          */
  276. X   char *start;               /* pointer to start of prefix */
  277. X   int  crossproduct = 0;     /* if 1 then computing X-prod */
  278. X
  279. X   start = s;
  280. X   res   = _strdup( "" );
  281. X   while( 1 )
  282. X      switch( *s ) {
  283. X         /* Termination, We halt at seeing a space or a tab or end of string.
  284. X          * We return the value of the result with any new macro's we scanned
  285. X          * or if we were computing cross_products then we return the new
  286. X          * cross_product.
  287. X          * NOTE:  Once we start computing cross products it is impossible to
  288. X          *        stop.  ie. the semantics are such that once a {} pair is
  289. X          *        seen we compute cross products until termination. */
  290. X
  291. X         case ' ':
  292. X         case '\t':
  293. X     case '\n':
  294. X         case '\0': 
  295. X     {
  296. X        char *tmp;
  297. X
  298. X        *ps = s;
  299. X        if( !crossproduct )
  300. X           tmp = _strjoin( res, start, (s-start), TRUE );
  301. X        else
  302. X        {
  303. X           tmp = _substr( start, s );
  304. X           tmp = _cross_prod( res, tmp );
  305. X        }
  306. X        return( tmp );
  307. X     }
  308. X         
  309. X         case '$':
  310. X         case '{':
  311. X     {
  312. X        /* Handle if it's a macro or if it's a {} construct.
  313. X         * The results of a macro expansion are handled differently based
  314. X         * on whether we have seen a {} beforehand. */
  315. X        
  316. X        char *tmp;
  317. X        tmp = _substr( start, s );          /* save the prefix */
  318. X
  319. X        if( *s == '$' ) {
  320. X           start = _scan_macro( s+1, &s );
  321. X
  322. X           if( crossproduct )
  323. X          res = _cross_prod( res, _strjoin( tmp, start, -1, TRUE ) );
  324. X           else {
  325. X          res = _strjoin(res,tmp = _strjoin(tmp,start,-1,TRUE),-1,TRUE);
  326. X          FREE( tmp );
  327. X           }
  328. X           FREE( start );
  329. X        }
  330. X        else if( s[1] != '{' ) {
  331. X           int ok;
  332. X           start = _scan_brace( s+1, &s, &ok );
  333. X          
  334. X           if( ok ) {
  335. X          res = _cross_prod( res, _cross_prod(tmp, start) );
  336. X          crossproduct = TRUE;
  337. X           }
  338. X           else {
  339. X          res =_strjoin(res,tmp=_strjoin(tmp,start,-1,TRUE),-1,TRUE);
  340. X          FREE( start );
  341. X          FREE( tmp   );
  342. X           }
  343. X        }
  344. X        else {    /* handle the {{ case */
  345. X           res = _strjoin( res, start, (s-start+1), TRUE );
  346. X           s  += 2;
  347. X           FREE( tmp );
  348. X        }
  349. X
  350. X        start = s;
  351. X     }
  352. X     break;
  353. X
  354. X     case '}':
  355. X        if( s[1] != '}' ) {
  356. X           /* error malformed macro expansion */
  357. X           s++;
  358. X        }
  359. X        else {    /* handle the }} case */
  360. X           res = _strjoin( res, start, (s-start+1), TRUE );
  361. X           s += 2;
  362. X           start = s;
  363. X        }
  364. X        break;
  365. X         
  366. X         default: s++;
  367. X      }
  368. X}
  369. X
  370. X
  371. X
  372. Xstatic char*
  373. X_scan_macro( s, ps )/*
  374. X======================
  375. X    This routine scans a macro use and expands it to the value.  It
  376. X    returns the macro's expanded value and modifies the pointer into the
  377. X    src string to point at the first character after the macro use.
  378. X    The types of uses recognized are:
  379. X
  380. X        $$        - expands to $
  381. X        $(name)        - expands to value of name
  382. X        ${name}        - same as above
  383. X        $($(name))    - recurses on macro names (any level)
  384. X    and
  385. X        $(func[,args ...] [data])
  386. X    and 
  387. X            $(name:modifier_list:modifier_list:...)
  388. X        
  389. X    see comment for Expand for description of valid modifiers.
  390. X
  391. X    NOTE that once a macro name bounded by ( or { is found only
  392. X    the appropriate terminator (ie. ( or } is searched for. */
  393. X
  394. Xchar *s;        /* pointer to start of src string   */
  395. Xchar **ps;        /* pointer to start pointer        */
  396. X{
  397. X   char sdelim;         /* start of macro delimiter         */
  398. X   char edelim;         /* corresponding end macro delim    */
  399. X   char *start;         /* start of prefix                  */
  400. X   char *macro_name;    /* temporary macro name             */
  401. X   char *recurse_name;  /* recursive macro name             */
  402. X   char *result;    /* result for macro expansion        */
  403. X   int  bflag = 0;      /* brace flag, ==0 => $A type macro */
  404. X   int  done  = 0;      /* != 0 => done macro search        */
  405. X   int  lev   = 0;      /* brace level                      */
  406. X   int  mflag = 0;      /* != 0 => modifiers present in mac */
  407. X   int  fflag = 0;    /* != 0 => GNU style function         */
  408. X   HASHPTR hp;        /* hash table pointer for macros    */
  409. X   
  410. X   DB_ENTER( "_scan_macro" );
  411. X
  412. X   /* Check for the simple $ at end of line case */
  413. X   if( !*s ) {
  414. X      *ps = s;
  415. X      DB_RETURN( _strdup("") );
  416. X   }
  417. X
  418. X   if( *s == '$' ) {    /* Take care of the simple $$ case. */
  419. X      *ps = s+1;
  420. X      DB_RETURN( _strdup("$") );
  421. X   }
  422. X
  423. X   sdelim = *s;         /* set and remember start/end delim */
  424. X   if( sdelim == '(' )
  425. X      edelim = ')';
  426. X   else
  427. X      edelim = '}';
  428. X
  429. X   start = s;           /* build up macro name, find its end*/
  430. X   while( !done ) {
  431. X      switch( *s ) {
  432. X         case '(':                /* open macro brace */
  433. X         case '{':
  434. X        if( *s == sdelim ) {
  435. X           lev++;
  436. X           bflag++;
  437. X        }
  438. X        break;
  439. X         
  440. X         case ':':                              /* halt at modifier */
  441. X            if( lev == 1 ) {
  442. X               done = TRUE;
  443. X               mflag = 1;
  444. X            }
  445. X            break;
  446. X
  447. X     case ' ':
  448. X     case '\t':
  449. X     case '\n':
  450. X        fflag = 1;
  451. X        break;
  452. X            
  453. X     case '\0':                /* check for null */
  454. X        *ps = s;
  455. X        if( lev ) {
  456. X           done  = TRUE;
  457. X           bflag = 0;
  458. X           s     = start;
  459. X        }
  460. X        break;
  461. X         
  462. X         case ')':                /* close macro brace */
  463. X         case '}':
  464. X        if( *s == edelim && lev ) --lev;
  465. X        /*FALLTHROUGH*/
  466. X
  467. X         default:
  468. X        done = !lev;
  469. X      }
  470. X      s++;
  471. X   }
  472. X
  473. X   /* Check if this is a $A type macro.  If so then we have to
  474. X    * handle it a little differently. */
  475. X   if( bflag )
  476. X      macro_name = _substr( start+1, s-1 );
  477. X   else
  478. X      macro_name = _substr( start, s );
  479. X
  480. X   /* Check to see if the macro name contains spaces, if so then treat it
  481. X    * as a GNU style function invocation and call the function mapper to
  482. X    * deal with it. */
  483. X   if( fflag )
  484. X      result = Exec_function(macro_name);
  485. X   else {
  486. X      /* Check if the macro is a recursive macro name, if so then
  487. X       * EXPAND the name before expanding the value */
  488. X      if( strchr( macro_name, '$' ) != NIL(char) ) {
  489. X     recurse_name = Expand( macro_name );
  490. X     FREE( macro_name );
  491. X     macro_name = recurse_name;
  492. X      }
  493. X
  494. X      /* Code to do value expansion goes here, NOTE:  macros whose assign bit
  495. X     is one have been evaluated and assigned, they contain no further
  496. X     expansions and thus do not need their values expanded again. */
  497. X
  498. X      if( (hp = GET_MACRO( macro_name )) != NIL(HASH) ) {
  499. X     if( hp->ht_flag & M_MARK )
  500. X        Fatal( "Detected circular macro [%s]", hp->ht_name );
  501. X
  502. X     /* for M_MULTI macro variable assignments */
  503. X     If_multi = hp->ht_flag & M_MULTI;
  504. X
  505. X     if( !(hp->ht_flag & M_EXPANDED) ) {
  506. X        hp->ht_flag |= M_MARK;
  507. X        result = Expand( hp->ht_value );
  508. X        hp->ht_flag ^= M_MARK;
  509. X     }
  510. X     else if( hp->ht_value != NIL(char) )
  511. X        result = _strdup( hp->ht_value );
  512. X     else
  513. X        result = _strdup( "" );
  514. X
  515. X     /*
  516. X      * Mark macros as used only if we are not expanding them for
  517. X      * the purpose of a .IF test, so we can warn about redef after use*/
  518. X
  519. X     if( !If_expand ) hp->ht_flag |= M_USED;
  520. X      }
  521. X      else
  522. X     result = _strdup( "" );
  523. X   }
  524. X
  525. X   if( mflag ) {
  526. X      char separator;
  527. X      int  modifier_list = 0;
  528. X      int  aug_mod       = FALSE;
  529. X      char *pat1;
  530. X      char *pat2;
  531. X      char *p;
  532. X
  533. X      /* Yet another brain damaged AUGMAKE kludge.  We should accept the 
  534. X       * AUGMAKE bullshit of $(f:pat=sub) form of macro expansion.  In
  535. X       * order to do this we will forgo the normal processing if the
  536. X       * AUGMAKE solution pans out, otherwise we will try to process the
  537. X       * modifiers ala dmake.
  538. X       *
  539. X       * So we look for = in modifier string.
  540. X       * If found we process it and not do the normal stuff */
  541. X
  542. X      for( p=s; *p && *p != '=' && *p != edelim; p++ );
  543. X
  544. X      if( *p == '=' ) {
  545. X     pat1 = _substr( s, p );
  546. X     for( s=p=p+1; (*p != edelim); p++ );
  547. X
  548. X     pat2   = _substr( s, p );
  549. X     result = Apply_edit( result, pat1, pat2, TRUE, TRUE );
  550. X     FREE( pat1 );
  551. X     FREE( pat2 );
  552. X     s = p;
  553. X     aug_mod = TRUE;
  554. X      }
  555. X
  556. X      if( !aug_mod )
  557. X     while( *s && *s != edelim ) {        /* while not at end of macro */
  558. X        switch( *s++ ) {
  559. X           case 'b':
  560. X           case 'B': modifier_list |= FILE_FLAG;            break;
  561. X
  562. X           case 'd':
  563. X           case 'D': modifier_list |= DIRECTORY_FLAG;         break;
  564. X
  565. X           case 'f':
  566. X           case 'F': modifier_list |= FILE_FLAG | SUFFIX_FLAG; break;
  567. X
  568. X           case 'S':
  569. X           case 's':
  570. X          if( modifier_list ) {
  571. X             Warning( "Edit modifier must appear alone, ignored");
  572. X             modifier_list = 0;
  573. X          }
  574. X          else {
  575. X             separator = *s++;
  576. X             for( p=s; *p != separator && *p != edelim; p++ );
  577. X
  578. X             if( *p == edelim )
  579. X                Warning("Syntax error in edit pattern, ignored");
  580. X             else {
  581. X            char *t1, *t2;
  582. X            pat1 = _substr( s, p );
  583. X            for(s=p=p+1; (*p != separator) && (*p != edelim); p++ );
  584. X            pat2 = _substr( s, p );
  585. X            t1 = Expand(pat1); FREE(pat1);
  586. X            t2 = Expand(pat2); FREE(pat2);
  587. X            result = Apply_edit( result, t1, t2, TRUE, FALSE );
  588. X            FREE( t1 );
  589. X            FREE( t2 );
  590. X             }
  591. X             s = p;
  592. X          }
  593. X          /* find the end of the macro spec, or the start of a new
  594. X           * modifier list for further processing of the result */
  595. X
  596. X          for( ; (*s != edelim) && (*s != ':'); s++ );
  597. X          if( *s == ':' ) s++;
  598. X          break;
  599. X
  600. X           case 'T':
  601. X           case 't':
  602. X          if( modifier_list ) {
  603. X             Warning( "Tokenize modifier must appear alone, ignored");
  604. X             modifier_list = 0;
  605. X          }
  606. X          else {
  607. X             char *msg = "Separator string must be quoted";
  608. X
  609. X             separator = *s++;
  610. X
  611. X             if( separator != '\"' )
  612. X            Warning( msg );
  613. X             else {
  614. X            /* we change the semantics to allow $(v:t")") */
  615. X            for (p = s; *p && *p != separator; p++)
  616. X               if (*p == '\\')
  617. X                  if (p[1] == '\\' || p[1] == '"')
  618. X                 p++;
  619. X            if( *p == 0 )
  620. X               Fatal( "Unterminated separator string" );
  621. X            else {
  622. X               pat1 = _substr( s, p );
  623. X               result = _tokenize( result, pat1 );
  624. X               FREE( pat1 );
  625. X            }
  626. X            s = p;
  627. X             }
  628. X
  629. X             /* find the end of the macro spec, or the start of a new
  630. X              * modifier list for further processing of the result */
  631. X
  632. X             for( ; (*s != edelim) && (*s != ':'); s++ );
  633. X             if( *s == ':' ) s++;
  634. X          }
  635. X          break;
  636. X
  637. X           case ':':
  638. X          if( modifier_list ) {
  639. X             result = _apply_modifiers( modifier_list, result );
  640. X             modifier_list = 0;
  641. X          }
  642. X          break;
  643. X
  644. X           default:
  645. X          Warning( "Illegal modifier in macro, ignored" );
  646. X          break;
  647. X        }
  648. X     }
  649. X
  650. X      if( modifier_list ) /* apply modifier */
  651. X         result = _apply_modifiers( modifier_list, result );
  652. X      
  653. X      s++;
  654. X   }
  655. X
  656. X   *ps = s;
  657. X   FREE( macro_name );
  658. X   DB_RETURN( result );
  659. X}
  660. X
  661. X
  662. X
  663. Xstatic char*
  664. X_scan_brace( s, ps, flag )/*
  665. X============================
  666. X      This routine scans for { token_list } pairs.  It expands the value of
  667. X      token_list by calling Expand on it.  Token_list may be anything at all.
  668. X      Note that the routine count's ballanced parentheses.  This means you
  669. X      cannot have something like { fred { joe }, if that is what you really
  670. X      need the write it as { fred {{ joe }, flag is set to 1 if all ok
  671. X      and to 0 if the braces were unballanced. */
  672. X      
  673. Xchar *s;
  674. Xchar **ps;
  675. Xint  *flag;
  676. X{
  677. X   char *t;
  678. X   char *start;
  679. X   char *res;
  680. X   int  lev  = 1;
  681. X   int  done = 0;
  682. X   
  683. X   DB_ENTER( "_scan_brace" );
  684. X
  685. X   start = s;
  686. X   while( !done )
  687. X      switch( *s++ ) {
  688. X         case '{': 
  689. X            if( *s == '{' ) break;              /* ignore {{ */
  690. X            lev++;
  691. X            break;
  692. X            
  693. X         case '}': 
  694. X            if( *s == '}' ) break;              /* ignore }} */
  695. X        if( lev )
  696. X           if( --lev == 0 ) done = TRUE;
  697. X        break;
  698. X
  699. X     case '$':
  700. X        if( *s == '{' || *s == '}' ) {
  701. X          if( (t = strchr(s,'}')) != NIL(char) )
  702. X             s = t;
  703. X          s++;
  704. X        }
  705. X        break;
  706. X         
  707. X         case '\0':
  708. X        if( lev ) {
  709. X           done = TRUE;
  710. X           s--;
  711. X           /* error malformed macro expansion */
  712. X        }
  713. X        break;
  714. X      }
  715. X
  716. X   start = _substr( start, (lev) ? s : s-1 );
  717. X
  718. X   if( lev ) {
  719. X      /* Braces were not ballanced so just return the string.
  720. X       * Do not expand it. */
  721. X       
  722. X      res   = _strjoin( "{", start, -1, FALSE );
  723. X      *flag = 0;
  724. X   }
  725. X   else {
  726. X      *flag = 1;
  727. X      res   = Expand( start );
  728. X
  729. X      if( (t = _strspn( res, " \t" )) != res ) strcpy( res, t );
  730. X   }
  731. X
  732. X   FREE( start );       /* this is ok! start is assigned a _substr above */
  733. X   *ps = s;
  734. X
  735. X   DB_RETURN( res );
  736. X}
  737. X
  738. X
  739. X
  740. Xstatic char*
  741. X_cross_prod( x, y )/*
  742. X=====================
  743. X      Given two strings x and y compute the cross-product of the tokens found
  744. X      in each string.  ie. if x = "a b" and y = "c d" return "ac ad bc bd".
  745. X
  746. X         NOTE:  buf will continue to grow until it is big enough to handle
  747. X                all cross product requests.  It is never freed!  (maybe I
  748. X            will fix this someday) */
  749. X      
  750. Xchar *x;
  751. Xchar *y;
  752. X{
  753. X   static char *buf;
  754. X   static int  buf_siz = 0;
  755. X   char *brkx;
  756. X   char *brky;
  757. X   char *cy;
  758. X   char *cx;
  759. X   char *res;
  760. X   int  i;
  761. X
  762. X   if( *x && *y ) {
  763. X      res = _strdup( "" ); cx = x;
  764. X      while( *cx ) {
  765. X     cy = y;
  766. X         brkx = _strpbrk( cx, " \t\n" );
  767. X     if( (brkx-cx == 2) && *cx == '\"' && *(cx+1) == '\"' ) cx = brkx;
  768. X
  769. X     while( *cy ) {
  770. X        brky = _strpbrk( cy, " \t\n" );
  771. X        if( (brky-cy == 2) && *cy == '\"' && *(cy+1) == '\"' ) cy = brky;
  772. X        i    = brkx-cx + brky-cy + 2;
  773. X
  774. X        if( i > buf_siz ) {        /* grow buf to the correct size */
  775. X           if( buf != NIL(char) ) FREE( buf );
  776. X           if( (buf = MALLOC( i, char )) == NIL(char))  No_ram();
  777. X           buf_siz = i;
  778. X        }
  779. X
  780. X        strncpy( buf, cx, (i = brkx-cx) );
  781. X        buf[i] = '\0';
  782. X        if (brky-cy > 0) strncat( buf, cy, brky-cy );
  783. X        strcat( buf, " " );
  784. X        res = _strjoin( res, buf, -1, TRUE );
  785. X        cy = _strspn( brky, " \t\n" );
  786. X     }
  787. X     cx = _strspn( brkx, " \t\n" );
  788. X      }
  789. X
  790. X      FREE( x );
  791. X      res[ strlen(res)-1 ] = '\0';
  792. X   }
  793. X   else
  794. X      res = _strjoin( x, y, -1, TRUE );
  795. X
  796. X   FREE( y );
  797. X   return( res );
  798. X}
  799. X
  800. X
  801. X
  802. Xstatic char*
  803. X_apply_modifiers( mod, src )/*
  804. X==============================
  805. X   This routine applies the appropriate modifiers to the string src
  806. X   and returns the proper result string */
  807. X
  808. Xint  mod;
  809. Xchar *src;
  810. X{
  811. X   char       *s;
  812. X   char    *e;
  813. X   TKSTR   str;
  814. X
  815. X   DB_ENTER( "_apply_modifiers" );
  816. X
  817. X   if( mod == (SUFFIX_FLAG | DIRECTORY_FLAG | FILE_FLAG) )
  818. X      DB_RETURN( src );
  819. X
  820. X   SET_TOKEN( &str, src );
  821. X   DB_PRINT( "mod", ("Source string [%s]", src) );
  822. X
  823. X   while( *(s = Get_token( &str, "", FALSE )) != '\0' ) {
  824. X      /* search for the directory portion of the filename.  If the
  825. X       * DIRECTORY_FLAG is set, then we want to keep the directory portion
  826. X       * othewise throw it away and blank out to the end of the token */
  827. X
  828. X      if( (e = basename(s)) != s)
  829. X     if( !(mod & DIRECTORY_FLAG) ) {
  830. X        strcpy(s, e);
  831. X        e = s+(str.tk_str-e);
  832. X        for(; e != str.tk_str; e++)
  833. X               *e = ' ';
  834. X     }
  835. X     else
  836. X        s = e;
  837. X
  838. X      /* search for the suffix, if there is none, treat it as a NULL suffix.
  839. X       * if no file name treat it as a NULL file name.  same copy op as
  840. X       * for directory case above */
  841. X
  842. X      e = strrchr( s, '.' );            /* NULL suffix if e=0 */
  843. X      if( e == NIL(char) ) e = s+strlen(s);
  844. X
  845. X      if( !(mod & FILE_FLAG) ) {
  846. X     strcpy( s, e );
  847. X     e = s+(str.tk_str-e);
  848. X     for( ; e != str.tk_str; e++ ) *e = ' ';
  849. X      }
  850. X      else
  851. X     s = e;
  852. X
  853. X      /* The last and final part.  This is the suffix case, if we don't want
  854. X       * it then just erase to the end of the token. */
  855. X
  856. X      if( s != NIL(char) )
  857. X     if( !(mod & SUFFIX_FLAG) )
  858. X        for( ; s != str.tk_str; s++ ) *s = ' ';
  859. X   }
  860. X
  861. X   /* delete the extra white space, it looks ugly */
  862. X   for( s = src, e = NIL(char); *s; s++ )
  863. X      if( *s == ' ' || *s == '\t' || *s == '\n' ) {
  864. X     if( e == NIL(char) )
  865. X        e = s;
  866. X      }
  867. X      else {
  868. X     if( e != NIL(char) ) {
  869. X        if( e+1 < s ) {
  870. X           strcpy( e+1, s );
  871. X           s = e+1;
  872. X           *e = ' ';
  873. X        }
  874. X        e = NIL(char);
  875. X     }
  876. X      }
  877. X
  878. X   if( e != NIL(char) )
  879. X      if( e < s )
  880. X     strcpy( e, s );
  881. X
  882. X   DB_PRINT( "mod", ("Result string [%s]", src) );
  883. X   DB_RETURN( src );
  884. X}
  885. X
  886. X
  887. X
  888. Xstatic char*
  889. X_tokenize( src, separator )/*
  890. X=============================
  891. X    Tokenize the input of src and join each token found together with
  892. X    the next token separated by the separator string.
  893. X
  894. X    When doing the tokenization, <sp>, <tab>, <nl>, and \<nl> all
  895. X    constitute white space. */
  896. X
  897. Xchar *src;
  898. Xchar *separator;
  899. X{
  900. X   TKSTR    tokens;
  901. X   char        *tok;
  902. X   char        *res;
  903. X   int        first = TRUE;
  904. X
  905. X   DB_ENTER( "_tokenize" );
  906. X
  907. X   SET_TOKEN( &tokens, src );
  908. X
  909. X
  910. X   /* map the escape codes in the separator string first */
  911. X
  912. X   for(tok=separator; (tok = strchr(tok,CONTINUATION_CHAR)) != NIL(char); tok++)
  913. X      Map_esc( tok );
  914. X
  915. X   DB_PRINT( "exp", ("Separator [%s]", separator) );
  916. X
  917. X   /* Build the token list */
  918. X   res = _strdup( "" );
  919. X   while( *(tok = Get_token( &tokens, "", FALSE )) != '\0' ) {
  920. X      DB_PRINT( "exp", ("Tokenizing [%s]", tok) );
  921. X
  922. X      if( first ) {
  923. X     FREE( res );
  924. X     res   = _strdup( tok );
  925. X     first = FALSE;
  926. X      }
  927. X      else {
  928. X           char *x;
  929. X     res = _strjoin(res, x =_strjoin(separator, tok, -1, FALSE), -1, TRUE);
  930. X     FREE( x );
  931. X      }
  932. X   }
  933. X
  934. X   FREE( src );
  935. X   DB_RETURN( res );
  936. X}
  937. SHAR_EOF
  938. echo "File expand.c is complete"
  939. chmod 0440 expand.c || echo "restore of expand.c fails"
  940. echo "x - extracting dump.c (Text)"
  941. sed 's/^X//' << 'SHAR_EOF' > dump.c &&
  942. X/* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/dump.c,v 1.1 90/10/06 12:03:37 dvadura Exp $
  943. X-- SYNOPSIS -- dump the internal dag to stdout.
  944. X-- 
  945. X-- DESCRIPTION
  946. X--    This file contains the routine that is called to dump a version of
  947. X--    the digested makefile to the standard output.  May be useful perhaps
  948. X--    to the ordinary user, and invaluable for debugging make.
  949. X-- 
  950. X-- AUTHOR
  951. X--      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  952. X--      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  953. X--
  954. X-- COPYRIGHT
  955. X--      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  956. X-- 
  957. X--      This program is free software; you can redistribute it and/or
  958. X--      modify it under the terms of the GNU General Public License
  959. X--      (version 1), as published by the Free Software Foundation, and
  960. X--      found in the file 'LICENSE' included with this distribution.
  961. X-- 
  962. X--      This program is distributed in the hope that it will be useful,
  963. X--      but WITHOUT ANY WARRANTY; without even the implied warrant of
  964. X--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  965. X--      GNU General Public License for more details.
  966. X-- 
  967. X--      You should have received a copy of the GNU General Public License
  968. X--      along with this program;  if not, write to the Free Software
  969. X--      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  970. X--
  971. X-- LOG
  972. X--     $Log:    dump.c,v $
  973. X * Revision 1.1  90/10/06  12:03:37  dvadura
  974. X * dmake Release, Version 3.6
  975. X * 
  976. X*/
  977. X
  978. X#include "db.h"
  979. X#include "extern.h"
  980. X
  981. X#define M_TEST    (M_PRECIOUS | M_VAR_MASK)
  982. X
  983. Xstatic    void    dump_normal_target ANSI((CELLPTR, HOWPTR, CELLPTR));
  984. Xstatic    void    dump_graph_node ANSI((CELLPTR));
  985. Xstatic    void    dump_name ANSI((HASHPTR, int));
  986. X
  987. X
  988. Xvoid
  989. XDump()/*
  990. X========  Dump onto standard output the digested makefile.  Note that
  991. X      the form of the dump is not representative of the contents
  992. X      of the original makefile contents at all */
  993. X{
  994. X   HASHPTR      hp;
  995. X   int          i;
  996. X
  997. X   DB_ENTER( "Dump" );
  998. X
  999. X   puts( "# Dump of dmake macro variables:" );
  1000. X   for( i=0; i<HASH_TABLE_SIZE; i++)
  1001. X      for( hp=Macs[i]; hp != NIL(HASH); hp = hp->ht_next ) {
  1002. X     int flag = hp->ht_flag;
  1003. X
  1004. X     printf( "%s ", hp->ht_name );
  1005. X     if( flag & M_EXPANDED ) putchar( ':' );
  1006. X     printf( "= " );
  1007. X     if( hp->ht_value != NIL(char) ) printf( hp->ht_value );
  1008. X     if( flag & M_PRECIOUS )
  1009. X        printf( "\t # PRECIOUS " );
  1010. X     putchar( '\n' );
  1011. X      }
  1012. X
  1013. X   puts( "\n#====================================" );
  1014. X   puts( "# Dump of targets:\n" );
  1015. X
  1016. X   for( i=0; i<HASH_TABLE_SIZE; i++ )
  1017. X      for( hp = Defs[i]; hp != NIL(HASH); hp = hp->ht_next )
  1018. X         if( !(hp->CP_OWNR->ce_flag & F_PERCENT) ) {
  1019. X        if( hp->CP_OWNR == Fringe_hd->cl_prq )
  1020. X           puts( "# ******* FIRST TARGET ********" );
  1021. X        dump_normal_target( hp->CP_OWNR, hp->CP_OWNR->CE_HOW, NIL(CELL) );
  1022. X     }
  1023. X
  1024. X   puts( "\n#====================================" );
  1025. X   puts( "# Dump of inference graph\n" );
  1026. X
  1027. X   for( i=0; i<HASH_TABLE_SIZE; i++ )
  1028. X      for( hp = Defs[i]; hp != NIL(HASH); hp = hp->ht_next )
  1029. X         if( (hp->CP_OWNR->ce_flag & F_PERCENT) &&
  1030. X        !(hp->CP_OWNR->ce_flag & F_MAGIC) )
  1031. X        dump_graph_node( hp->CP_OWNR );
  1032. X
  1033. X   DB_VOID_RETURN;
  1034. X}
  1035. X
  1036. X
  1037. X
  1038. Xvoid
  1039. XDump_recipe( sp )/*
  1040. X===================
  1041. X   Given a string pointer print the recipe line out */
  1042. XSTRINGPTR sp;
  1043. X{
  1044. X   char *st;
  1045. X   char *nl;
  1046. X
  1047. X   if( sp == NIL(STRING) ) return;
  1048. X
  1049. X   putchar( '\t' );
  1050. X   if( sp->st_attr & A_SILENT ) putchar( '@' );
  1051. X   if( sp->st_attr & A_IGNORE ) putchar( '-' );
  1052. X   if( sp->st_attr & A_SHELL  ) putchar( '+' );
  1053. X
  1054. X   st = sp->st_string;
  1055. X   for( nl=strchr(st,'\n'); nl != NIL( char); nl=strchr(st,'\n') ) {
  1056. X      *nl = '\0';
  1057. X      printf( "%s\\\n", st );
  1058. X      *nl = '\n';
  1059. X      st  = nl+1;
  1060. X   }
  1061. X   printf( "%s\n", st );
  1062. X}
  1063. X
  1064. X
  1065. Xstatic char *_attrs[] = { ".PRECIOUS", ".SILENT", ".LIBRARY",
  1066. X   ".EPILOG", ".PROLOG", ".IGNORE", ".SYMBOL", ".NOINFER",
  1067. X   ".UPDATEALL", ".SEQUENTIAL", ".SETDIR=", ".USESHELL", ".SWAP", ".MKSARGS" };
  1068. X
  1069. Xstatic void
  1070. Xdump_normal_target( cp, hw, prq )/*
  1071. X===================================
  1072. X    Dump in makefile like format the dag information */
  1073. XCELLPTR cp;
  1074. XHOWPTR  hw;
  1075. XCELLPTR prq;
  1076. X{
  1077. X   register LINKPTR   lp;
  1078. X   register STRINGPTR sp;
  1079. X   t_attr          attr;
  1080. X   unsigned int          k;
  1081. X
  1082. X   DB_ENTER( "dump_normal_target" );
  1083. X
  1084. X   if( hw == NIL(HOW) ) { DB_VOID_RETURN; }
  1085. X   if( hw->hw_next != NIL(HOW) ) dump_normal_target( cp, hw->hw_next, prq );
  1086. X
  1087. X   dump_name( cp->ce_name, FALSE );
  1088. X
  1089. X   for( k=0, attr=1; attr <= MAX_ATTR; attr <<= 1, k++ )
  1090. X      if( (cp->ce_attr & attr) || ((hw->hw_attr & A_SHELL)&attr) ) {
  1091. X         printf( "%s%s ", _attrs[k],
  1092. X         (attr != A_SETDIR) ? "" : (cp->ce_dir?cp->ce_dir:"") );
  1093. X      }
  1094. X         
  1095. X   putchar( ':' );
  1096. X
  1097. X   if( cp->ce_flag & F_MULTI )  putchar( ':' );
  1098. X   if( hw->hw_flag & F_SINGLE ) putchar( '!' );
  1099. X   putchar( ' ' );
  1100. X
  1101. X   if( prq != NIL(CELL) ) dump_name( prq->ce_name, FALSE );
  1102. X   for( lp = hw->hw_prq; lp != NIL(LINK); lp = lp->cl_next )
  1103. X      dump_name( lp->cl_prq->ce_name, FALSE );
  1104. X
  1105. X   if( (lp = hw->hw_indprq) != NIL(LINK) ) {
  1106. X      for( ; lp != NIL(LINK); lp = lp->cl_next )
  1107. X     dump_name( lp->cl_prq->ce_name, TRUE );
  1108. X   }
  1109. X
  1110. X   putchar( '\n' );
  1111. X   if( hw->hw_flag & F_GROUP ) {
  1112. X      if( hw->hw_attr & A_IGNORE ) putchar( '-' );
  1113. X      if( hw->hw_attr & A_SILENT ) putchar( '@' );
  1114. X      puts( "[" );
  1115. X   }
  1116. X
  1117. X   for( sp = hw->hw_recipe; sp != NIL(STRING); sp = sp->st_next )
  1118. X      Dump_recipe( sp );
  1119. X   if( hw->hw_flag & F_GROUP ) puts( "]" );
  1120. X
  1121. X   putchar( '\n' );
  1122. X   DB_VOID_RETURN;
  1123. X}
  1124. X
  1125. X
  1126. Xstatic void
  1127. Xdump_name( hp, quote )/*
  1128. X========================
  1129. X    print out a name */
  1130. XHASHPTR hp;
  1131. Xint     quote;
  1132. X{
  1133. X   if( quote ) putchar('\'');
  1134. X   printf( "%s", hp->ht_name );
  1135. X   if( quote ) putchar('\'');
  1136. X   putchar(' ');
  1137. X}
  1138. X
  1139. X
  1140. Xstatic void
  1141. Xdump_graph_node( cp )/*
  1142. X=======================*/
  1143. XCELLPTR cp;
  1144. X{
  1145. X   EDGEPTR    pe;
  1146. X
  1147. X   pe = cp->CE_EDGES; 
  1148. X
  1149. X   if( pe != NIL(EDGE) )
  1150. X      do {
  1151. X     dump_normal_target( cp, pe->ed_how, pe->ed_prq );
  1152. X     pe = pe->ed_next;
  1153. X      }
  1154. X      while( pe != cp->CE_EDGES );
  1155. X}
  1156. SHAR_EOF
  1157. chmod 0440 dump.c || echo "restore of dump.c fails"
  1158. echo "x - extracting dmake.h (Text)"
  1159. sed 's/^X//' << 'SHAR_EOF' > dmake.h &&
  1160. X/* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/dmake.h,v 1.1 90/10/06 12:04:20 dvadura Exp $
  1161. X-- SYNOPSIS -- global defines for dmake.
  1162. X-- 
  1163. X-- DESCRIPTION
  1164. X--     All the interesting bits and flags that dmake uses are defined here.
  1165. X--
  1166. X-- AUTHOR
  1167. X--      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  1168. X--      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  1169. X--
  1170. X-- COPYRIGHT
  1171. X--      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  1172. X-- 
  1173. X--      This program is free software; you can redistribute it and/or
  1174. X--      modify it under the terms of the GNU General Public License
  1175. X--      (version 1), as published by the Free Software Foundation, and
  1176. X--      found in the file 'LICENSE' included with this distribution.
  1177. X-- 
  1178. X--      This program is distributed in the hope that it will be useful,
  1179. X--      but WITHOUT ANY WARRANTY; without even the implied warrant of
  1180. X--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1181. X--      GNU General Public License for more details.
  1182. X-- 
  1183. X--      You should have received a copy of the GNU General Public License
  1184. X--      along with this program;  if not, write to the Free Software
  1185. X--      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1186. X--
  1187. X-- LOG
  1188. X--     $Log:    dmake.h,v $
  1189. X * Revision 1.1  90/10/06  12:04:20  dvadura
  1190. X * dmake Release, Version 3.6
  1191. X * 
  1192. X*/
  1193. X
  1194. X#ifndef _DMAKE_INCLUDED_
  1195. X#define _DMAKE_INCLUDED_
  1196. X
  1197. X#define MAX_INC_DEPTH     10     /* max of ten nested include files      */
  1198. X#define MAX_COND_DEPTH      20     /* max nesting level of conditionals    */
  1199. X#define ERROR_EXIT_VALUE  255     /* return code of aborted make         */
  1200. X#define CONTINUATION_CHAR '\\'   /* line continuation \<nl>              */
  1201. X#define ESCAPE_CHAR       '\\'   /* escape char for used chars           */
  1202. X#define COMMENT_CHAR      '#'    /* start of comment chars               */
  1203. X#define TGT_DEP_SEP       ':'    /* separator for targets and dependents */
  1204. X#define CONDSTART      '.'     /* start of conditional token    eg .IF     */
  1205. X#define DEF_MAKE_PNAME    "dmake"/* default name to use as name of make  */
  1206. X
  1207. X
  1208. X/* ............... Hashing function constants ......................... */
  1209. X#define HASH_TABLE_SIZE  200            /* See hash.c for description   */
  1210. X
  1211. X
  1212. X/* Bit flags for cells and macro definitions. */
  1213. X#define M_DEFAULT        0x0000         /* default flag value           */
  1214. X#define M_MARK           0x0001         /* mark for circularity checks  */
  1215. X#define M_PRECIOUS       0x0002         /* keep macro, same as A_PRE... */
  1216. X#define M_MULTI          0x0004         /* multiple redefinitions ok!   */
  1217. X#define M_EXPANDED       0x0008         /* macro has been assigned      */
  1218. X#define M_USED         0x0010        /* macro has been expanded    */
  1219. X#define M_LITERAL     0x0020        /* don't strip w/s on macro def */
  1220. X#define    M_NOEXPORT     0x0040        /* don't export macro for -x    */
  1221. X#define M_FORCE         0x0080        /* Force a macro redefinition    */
  1222. X#define M_VAR_BIT        0x1000         /* macro bit variable           */
  1223. X#define M_VAR_CHAR       0x2000         /* macro char variable          */
  1224. X#define M_VAR_STRING     0x4000         /* macro string variable        */
  1225. X#define M_VAR_INT     0x8000        /* macro integer variable    */
  1226. X
  1227. X#define M_VAR_MASK       0xf000         /* macro variable mask          */
  1228. X
  1229. X
  1230. X
  1231. X/* Global and target attribute flag definitions.
  1232. X * If you change the values of these or re-order them make appropriate changes
  1233. X * in dump.c so that the output of dmake -p matches the attribute info for a
  1234. X * target. */
  1235. X
  1236. X#define A_DEFAULT        0x00000        /* default flag value           */
  1237. X#define A_PRECIOUS       0x00001        /* object is precious           */
  1238. X#define A_SILENT         0x00002        /* don't echo commands          */
  1239. X#define A_LIBRARY        0x00004        /* target is an archive        */
  1240. X#define A_EPILOG         0x00008        /* insert shell epilog code     */
  1241. X#define A_PROLOG         0x00010        /* insert shell prolog code     */
  1242. X#define A_IGNORE         0x00020        /* ignore errors                */
  1243. X#define A_SYMBOL     0x00040    /* lib member is a symbol    */
  1244. X#define A_NOINFER     0x00080    /* no trans closure from cell    */
  1245. X#define A_UPDATEALL     0x00100    /* all targets of rule modified */
  1246. X#define A_SEQ         0x00200    /* sequential make attribute    */
  1247. X#define A_SETDIR         0x00400        /* cd to dir when making target */
  1248. X#define A_SHELL         0x00800    /* appears only on HOW nodes    */
  1249. X#define A_SWAP         0x01000    /* swap on exec.        */
  1250. X#define A_MKSARGS     0x02000    /* use MKS argument swapping    */
  1251. X#define MAX_ATTR     A_MKSARGS    /* highest valid attribute    */
  1252. X#define A_LIBRARYM       0x04000        /* target is an archive member  */
  1253. X#define A_FRINGE     0x08000    /* cell is on the fringe    */
  1254. X#define A_COMPOSITE     0x10000    /* member of lib(targ) name    */
  1255. X#define A_FFNAME     0x20000    /* if set, free ce_fname in stat*/
  1256. X#define A_UPDATED     0x40000    /* Used to mark cell as updated */
  1257. X
  1258. X
  1259. X/* Global and target bit flag definitions */
  1260. X
  1261. X#define F_DEFAULT        0x0000         /* default flag value           */
  1262. X#define F_MARK         0x0001        /* circularity check mark    */
  1263. X#define F_MULTI         0x0002        /* multiple rules for target    */
  1264. X#define F_SINGLE     0x0004        /* exec rules one/prerequisite  */
  1265. X#define F_TARGET     0x0008        /* marks a target        */
  1266. X#define F_RULES          0x0010         /* indicates target has rules   */
  1267. X#define F_GROUP          0x0020         /* indicates that rules are to  */
  1268. X                        /* fed to the shell as a group  */
  1269. X
  1270. X#define F_TRANS         0x0040        /* same as F_STAT not used tgthr*/
  1271. X#define F_STAT         0x0040        /* target already stated    */
  1272. X#define F_VISITED     0x0080        /* target scheduled for make    */
  1273. X#define F_USED         0x0080        /* used in releparse.c        */
  1274. X#define F_SPECIAL     0x0100        /* marks a special target    */
  1275. X#define F_DFA          0x0200        /* bit for marking added DFA    */
  1276. X#define F_EXPLICIT     0x0400        /* explicit target in makefile  */
  1277. X#define F_PERCENT     0x0800        /* marks a target as a % rule    */
  1278. X#define F_REMOVE     0x1000        /* marks an intermediate target */
  1279. X#define F_MAGIC         0x2000        /* marks a magic target        */
  1280. X#define F_INFER         0x4000        /* target is result of inference*/
  1281. X#define F_MADE         0x8000        /* target is manufactured    */
  1282. X
  1283. X
  1284. X/* Definitions for the Parser states */
  1285. X#define NORMAL_SCAN    0     /* normal processing state */
  1286. X#define RULE_SCAN      1     /* scan of rule text       */
  1287. X
  1288. X/* definitions for macro operator types */
  1289. X#define M_OP_EQ  1           /* macro operation is '='  */
  1290. X#define M_OP_CL  2           /* macro operation is ':=' */
  1291. X#define M_OP_PL  3           /* macro operation is '+=' */
  1292. X#define M_OP_PLCL 4          /* macro operation is '+:='*/
  1293. X#define M_OP_DF  5         /* macro operation is '*=' */
  1294. X#define M_OP_DFCL 6         /* macro operation is '*:='*/
  1295. X
  1296. X/* definitions for rule operator types */
  1297. X#define R_OP_CL   1           /* rule operation is ':'   */
  1298. X#define R_OP_DCL  2           /* rule operation is '::'  */
  1299. X#define R_OP_BG   4           /* rule operation is ':!'  */
  1300. X#define R_OP_UP   8           /* rule operation is ':^'  */
  1301. X#define R_OP_MI  16           /* rule operation is ':-'  */
  1302. X
  1303. X
  1304. X/* special target definitions for use inside dmake */
  1305. X#define ST_IF        1
  1306. X#define ST_ELSE        2
  1307. X#define ST_END        3
  1308. X#define ST_REST        4    /* remaining special targets */
  1309. X#define ST_INCLUDE    5
  1310. X#define ST_SOURCE    7
  1311. X#define ST_EXPORT    8
  1312. SHAR_EOF
  1313. echo "End of part 21"
  1314. echo "File dmake.h is continued in part 22"
  1315. echo "22" > s2_seq_.tmp
  1316. exit 0
  1317.  
  1318.